package com.rc.saas.tenant.common.utils;

import com.rc.saas.tenant.common.annotation.Excel;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.HorizontalAlignment;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

/**
 * EXCEL导出工具
 */
public class ExcelExportUtil {
    /**
     * 下载excel
     * @param response
     * @param result
     * @param
     * @param sheetName
     * @param fileName
     * @throws Exception
     */
    public static void downLoadExcel(HttpServletResponse response, List<?> result, String sheetName, String fileName)
            throws Exception {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        HSSFWorkbook wb = MakeExcel(result, sheetName);
        wb.write(os);
        byte[] content = os.toByteArray();
        InputStream is = new ByteArrayInputStream(content);
        // 设置response参数，可以打开下载页面
        response.reset();
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(), "iso-8859-1") + ".xls");// iso-8859-1
        response.setHeader("Set-Cookie", "fileDownload=true; path=/");
        ServletOutputStream out = response.getOutputStream();
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(is);
            bos = new BufferedOutputStream(out);
            byte[] buff = new byte[2048];
            int bytesRead;
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bis != null)
                bis.close();
            if (bos != null)
                bos.close();
        }
    }

    /**
     * 创建excel表
     * @param result
     * @param
     * @param sheetName
     * @return
     */
    public static HSSFWorkbook MakeExcel(List<?> result, String sheetName) throws Exception {

        HSSFWorkbook wb = new HSSFWorkbook();

        //处理Excel生成多个工作表
        //定义为每个工作表数据为5000条
        if (result != null && result.size() > 5000) {
            int k = (result.size() + 5000) / 5000;
            for (int i = 1; i <= k; i++) {
                if (i < k) {
                    createSheet(result.subList((i - 1) * 5000, i * 5000), sheetName + i, wb);
                } else {
                    createSheet(result.subList((i - 1) * 5000, result.size()), sheetName + i, wb);
                }
            }
        } else {
            createSheet(result, sheetName, wb);
        }
        return wb;
    }

    private static void createSheet(List<?> result, String sheetName, HSSFWorkbook wb) throws Exception {
        // 2.在workbook中添加一个sheet，对应Excel中的一个sheet
        HSSFSheet sheet = wb.createSheet(sheetName);
        // 3.在sheet中添加表头第0行，老版本poi对excel行数列数有限制short
        HSSFRow row = sheet.createRow((int) 0);
        // 4.创建单元格，设置值表头，设置表头居中
        HSSFCellStyle style = wb.createCellStyle();
        // 居中格式
        //style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        style.setAlignment(HorizontalAlignment.CENTER);

        if (result == null || result.isEmpty()) {
            HSSFCell cell = row.createCell(0);
            cell.setCellValue("无数据!");
            cell.setCellStyle(style);
        } else {
            setRowValue(result, sheet, row, style);
        }
    }

    private static void setRowValue(List<?> result, HSSFSheet sheet, HSSFRow row, HSSFCellStyle style) throws Exception {
        Class<?> resultClass = result.get(0).getClass();
        Field[] fields = resultClass.getDeclaredFields();
        Method[] methods = new Method[fields.length];
        String[] contents = new String[fields.length];
        Excel[] excels = new Excel[fields.length];
        Excel excel = null;
        for (int i = 0; i < fields.length; i++) {
            excel = fields[i].getAnnotation(Excel.class);
            contents[i] = excel.title();
            String methodName = "get" + fields[i].getName().substring(0, 1).toUpperCase() + fields[i].getName().substring(1);
            Method method = resultClass.getMethod(methodName, null);
            methods[i] = method;
            excels[i] = excel;
        }
        // 设置表头
        createCell(row, style, contents);

        for (int j = 0; j < result.size(); j++) {
            for (int k = 0; k < methods.length; k++) {

                try {
                    Object obj = methods[k].invoke(result.get(j), null);
                    if (obj != null) {
                        contents[k] = obj.toString();
                    } else {
                        contents[k] = "";
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                if (excels[k].index().length > 0) {
                    contents[k] = getExcelValue(excels[k], contents[k]);
                }
            }
            row = sheet.createRow(j + 1);
            // 给每行一一对应的添加数据
            createCell(row, style, contents);

        }
    }

    private static void createCell(HSSFRow row, HSSFCellStyle style, String[] contents) {
        for (int i = 0; i < contents.length; i++) {
            HSSFCell cell = row.createCell(i);
            cell.setCellValue(contents[i]);
            cell.setCellStyle(style);
        }
    }

    private static String getExcelValue(Excel excel, String index) {
        for (int i = 0; i < excel.index().length; i++) {
            if (excel.index()[i].equals(index)) {
                return excel.value()[i];
            }
        }
        return null;
    }

    public static String turnRtua(String rtua, boolean flag) {
        StringBuffer rt = new StringBuffer();
        if (StringUtil.isNotBlank(rtua)) {
            if (flag) {
                rt.append(rtua.substring(0, 2)).append(" ").append(rtua.substring(2, 4)).append(" ").append(rtua.substring(6, 8))
                        .append(" ") // 后两位要反转
                        .append(rtua.substring(4, 6));
            } else {
                String[] rts = rtua.split(" ");
                rt.append(rts[0]).append(rts[1]).append(rts[3]).append(rts[2]);
            }
        }
        return rt.toString();
    }


}
